【AWS Amplify 노하우 시리즈】 2. enum 타입 필드는 Search API 에서 사용할 수 없어요
안녕하세요!ㅎㅎ Classmethod 컨설팅부 소속 김태우입니다.
지난번 글에 이어 Amplify 시리즈 두번째 글입니다! 이번 글도 역시나 입문자를 대상으로 하는 글이 아니라서 Amplify 의 기초부분은 다루지 않고 있고, Amplify 를 직접 프로젝트에 활용할 때의 팁에 대해 적어보려고 합니다.
이번 글에서는 특히, Search API 를 사용할 때 enum 타입에 대한 제약사항과 이 제약사항을 벗어나기 위한 간접적인 해결책(workaround)를 제시합니다. 어찌보면 굉장히 간단한 글이 될 것 같지만, 미리 읽어두고 알아놓으면 수고로움을 덜어준다는거!ㅎㅎ
그럼 시작하겠습니다! :)
응?? 뭐가 안된다구??
Amplify 의 API 를 GraphQL (실제로는 AppSync 가 사용됨) 타입으로 선택하여 @searchable 디렉티브를 스키마에 추가하면 자동으로 Search 관련 API 를 생성해줍니다. 좀 더 구체적으로,
type Post @model @searchable { id: ID! title: String! content: String! createdAt: AWSDateTime updatedAt: AWSDateTime }
와 같이, Post 타입의 스키마에 @searchable 디렉티브를 추가하고 amplify push
해주면 AppSync 에 등록할 수 있는 훨씬 더 상세한 스키마파일로 변환해주는 과정을 거치게 됩니다.
amplify/backend/api/${API명}/build/schema.graphql
파일을 열어보면 amplify/backend/api/${API명}/schema.graphql
보다 훨씬 상세한 스키마 파일을 확인하실 수 있습니다.
이 때, Query 타입을 보면,
... type Query { getPost(id: ID!): Post listPosts(filter: ModelPostFilterInput, limit: Int, nextToken: String): ModelPostConnection searchPosts(filter: SearchablePostFilterInput, sort: SearchablePostSortInput, limit: Int, nextToken: String): SearchablePostConnection } ...
와 같이 searchPosts() 가 자동으로 생성되었음을 확인할 수 있습니다. SearchablePostFilterInput 타입의 filter 파라미터를 인풋으로 받는데요, 이때 SearchablePostFilterInput 를 찾아서 확인해보면,
... input SearchablePostFilterInput { id: SearchableIDFilterInput title: SearchableStringFilterInput content: SearchableStringFilterInput createdAt: SearchableStringFilterInput updatedAt: SearchableStringFilterInput and: [SearchablePostFilterInput] or: [SearchablePostFilterInput] not: SearchablePostFilterInput } ...
와 같이, Post 타입에 선언해두었던 모든 id, title, content, createdAt, updatedAt 필드가 모두 searchable filter 로 등록된 것을 확인할 수가 있습니다.
자, 이제 처음의 Post 타입을 한번 아래와 같이 변경한 후에 amplify push 를 실행해보겠습니다.
type Post @model @searchable { id: ID! title: String! content: String! hit: Int! # 조회수 postType: PostTypeEnum! # 글 종류 authorEmail: AWSEmail! # 작성자 이메일주소 postUrl: AWSURL! # 본문 URL createdAt: AWSDateTime updatedAt: AWSDateTime } enum PostTypeEnum { ANNOUNCEMENT # 공지사항 NORMAL # 일반글 ADVERTISEMENT # 광고 }
$ amplify push
그러면 아래와 같이 build/schema.graphql
의 SearchablePostFilterInput 은 아래와 같이 업데이트됩니다.
... input SearchablePostFilterInput { id: SearchableIDFilterInput title: SearchableStringFilterInput content: SearchableStringFilterInput hit: SearchableIntFilterInput authorEmail: SearchableStringFilterInput postUrl: SearchableStringFilterInput createdAt: SearchableStringFilterInput updatedAt: SearchableStringFilterInput and: [SearchablePostFilterInput] or: [SearchablePostFilterInput] not: SearchablePostFilterInput } ...
어라? 잠깐...!? 여기서 이상한 점을 느끼셨나요?
PostTypeEnum 타입의 postType 필드에 대한 필터가 생성되지 않았습니다! Amplify 공식문서에서 찾아보면,
A complete list of searchable operations per GraphQL type supported as of today
enum 은 @searchable 에서 서포트 하지 않고 있는군요..
이 글을 작성하고 있는 불과 열흘전까지도 Amplify Github 의 Issues 에는 이 기능을 서포트 해달라고하는 요청이 넘쳐나고 있습니다.
Unable to search on enum field with @searchable #3248
어떻게 해결하는 게 좋을까요??
사실 저도 딱히 엄청한 노하우나 팁이 있는 것은 아닙니다. 다만, 이러한 이슈가 있다는 것을 널리 공유하고, 제가 어떻게 이러한 이슈를 회피해서 Amplify 를 활용하고 있는지에 대한 사소한 의견을 공유하고 싶어서 글을 작성하고 있습니다. 그러니 더 좋은 솔루션을 아시는 분은 AWSKRUG 의 #amplify 채널에서 @twkiiim 에게 멘션 걸어서 알려주세요!ㅋㅋ
같은 필드, 다른 타입을 사용하기
결론부터 말씀드리면, 저는 아래와 같이 String 타입의 필드를 하나더 추가해서 사용하고 있습니다.
type Post @model @searchable { id: ID! title: String! content: String! hit: Int! # 조회수 postType: PostTypeEnum! # 글 종류 authorEmail: AWSEmail! # 작성자 이메일주소 postUrl: AWSURL! # 본문 URL createdAt: AWSDateTime updatedAt: AWSDateTime ## temporary searchable fields _postType: String! # postType 을 Searchable 필터로 사용하기 위한 임시 필드 ... } enum PostTypeEnum { ANNOUNCEMENT # 공지사항 NORMAL # 일반글 ADVERTISEMENT # 광고 }
즉, 데이터를 생성할 때 PostTypeEnum 타입의 변수를 아래와 같이 어사인해서 데이터를 생성하는 것이죠!
... postInput.postType = PostTypeEnum.NORMAL; postInput._postType = PostTypeEnum.NORMAL; ...
실제로 javascript 에서는 enum 타입이 스트링과 동일하게 취급되기 때문에 이러한 어프로치가 동작합니다. 그리고, 검색시에는 String 타입으로 선언된 _postType 필드를 활용하여 postType 으로 필터링이 가능합니다.
이런 귀찮은 걸 하라고??
물론 postType 필드를 생성/수정 할 때마다 이러한 작업을 해줘야하는 번거로움이 있지만, Amplify 를 활용하게 될 주 타겟이 빠르게 MVP 를 만들어내고자하는 완전초기 스타트업이라는 점을 감안하면, 이정도 번거로움은 충분히 감수할 만 하다고 생각합니다. 스키마 선언만으로도 그 귀찮은 CRUD API 는 물론, Search API 까지 자동으로 생성해주니까요!
마치며
이번 글에서는 Search API 를 활용할 때 enum 타입으로 선언된 필드가 Searchable 필터에 포함되지 않는다는 점과, 이를 해결하기 위한 간단한 workaround 에 대해 공유하였습니다!
이상, 컨설팅부의 김태우였습니다! :D